//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <core.h>
#include <crust.h>
#include <init.h>

STATIC DECL_CODEINIT void *NewProxyEntryTable();

EXTERN_C void SysProxyEntry(void);

EXTERN DECL_CODEINIT bool_t CDECL InitProxyEntryTable()
{
    assert(0 == g_initPageDir[PAGEDIR_INDEX(PROXY_ENTRY_BASE)].uValue);

    // Alloc the page table's memory
    PageTabEntry *pPageTab = (PageTabEntry *)DzAllocKernelPage();
    if (NULL == pPageTab) return FALSE;

    memset(pPageTab, 0, c_uSizeOfPageTab);

    // Alloc use page
    void *pProxyEntryTable = NewProxyEntryTable();
    if (NULL == pProxyEntryTable) {
        DzFreeKernelPage(pPageTab);
        return FALSE;
    }

    // executable is the default attribute.
    pPageTab[PAGETAB_INDEX(PROXY_ENTRY_BASE)].uValue =
        ((PHYSADDR(pProxyEntryTable) >> PAGE_SHIFT) << 6)
        | PageEntryFlag_Global | PageEntryFlag_Valid
        | PageEntryFlag_Writable | PageEntryFlag_CacheableNoncoherent;

    g_initPageDir[PAGEDIR_INDEX(PROXY_ENTRY_BASE)].uValue = (uint32_t)pPageTab;

    FillGlobalTlb(PROXY_ENTRY_BASE);

    return TRUE;
}

STATIC DECL_CODEINIT void *NewProxyEntryTable()
{
    void *pProxyEntryTable = (char *)DzAllocKernelPage();
    if (NULL == pProxyEntryTable) return NULL;

    char *p = (char *)pProxyEntryTable;
    for (int n = 0; n < PROXY_ENTRY_NUM; n++) {
        memcpy(p, (void *)&SysProxyEntry, PROXY_ENTRY_SIZE);
        p += PROXY_ENTRY_SIZE;
    }

    FlushCache();

    return pProxyEntryTable;
}
